home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume89
/
graphics
/
mandel18.2
< prev
next >
Wrap
Internet Message Format
|
1989-05-18
|
54KB
Path: xanth!ames!amdahl!oliveb!sun!swap!page
From: page%swap@Sun.COM (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v89i143: mandel - mandelobrot generator v180, Part02/04
Message-ID: <105554@sun.Eng.Sun.COM>
Date: 17 May 89 15:53:24 GMT
Sender: news@sun.Eng.Sun.COM
Lines: 2046
Approved: page@sun.com
Submitted-by: u211344@hnykun11.bitnet (Olaf 'Rhialto' Seibert)
Posting-number: Volume 89, Issue 143
Archive-name: graphics/mandel180.2
# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
# GotMenu.c
# Jiff.c
# This is archive 2 of a 4-part kit.
# This archive created: Wed May 17 20:45:12 1989
echo "extracting GotMenu.c"
sed 's/^X//' << \SHAR_EOF > GotMenu.c
X/*
X * M A N D E L B R O T C O N S T R U C T I O N S E T
X *
X * (C) Copyright 1989 by Olaf Seibert.
X * Mandel may be freely distributed. See file 'doc/Notice' for details.
X *
X * GotMenu and some (many) related things.
X */
X
X#include <exec/types.h>
X#include <intuition/intuition.h>
X#include "mandel.h"
X#ifdef DEBUG
X# include <stdio.h>
X# undef STATIC
X# define STATIC /* EMPTY */
X#endif
X
Xextern double ReMouse, ImMouse;
Xextern UBYTE IPlotNr, EPlotNr;
Xextern void UpdateDrwCm();
X
XTEXT FileName[FNAME_SIZE+1] = "Mandel.pic";
XTEXT DirName[DNAME_SIZE+2] = "";
XUBYTE Buffer[5][20];
X
Xint (*DepthFuncArray[])() = {
X ZQuadMinC, ZC1MinZ, Z3PlusZCMin1MinC, UserProgFunc, I_ZQuadMinC
X};
X
Xvoid (*IPlotFuncArray[])() = {
X None, PlotZ
X};
X
Xvoid (*EPlotFuncArray[])() = {
X PlotIterationCount, PlotZ,
X};
X
X/* Forward declarations of static procedures */
XSTATIC void PrjNew();
X
Xvoid GotMenu(Code)
XUSHORT Code;
X{
X static void (*MenuFunc[])()= {
X CprMenu, PrjMenu, OptMenu, DrwMenu, BatchMenu
X };
X while (Code != MENUNULL) {
X (*MenuFunc[MENUNUM(Code)]) (Code);
X Code = ItemAddress(MandelMenu, (long) Code)->NextSelect;
X }
X}
X
Xvoid CprMenu(Code)
XUSHORT Code;
X{
X extern long Revision; /* From IncRev */
X ULONG OldIDCMP = MainWindow->IDCMPFlags;
X
X#define DATE "16 April 1989 V1.3 ("
X#define strlen_DATE 20
X
X static UBYTE DateVersion[strlen_DATE+9] = DATE;
X
X static struct IntuiText Body[] =
X {
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X 10, 15, NULL, (UBYTE *)"Mandelbrot Construction Set", &Body[1] },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X 10, 30, NULL, (UBYTE *)"By KosmoSoft Productions", &Body[2] },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X 10, 40, NULL, DateVersion, &Body[3] },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X 10, 55, NULL, (UBYTE *)"Ohh, please Copy-Me!", NULL }
X },
X ExitText =
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X AUTOLEFTEDGE, AUTOTOPEDGE, NULL, (UBYTE *)" OK ", NULL };
X
X sprintf(&DateVersion[strlen_DATE], "%ld)", Revision);
X
X ModifyIDCMP(MainWindow, OldIDCMP &~ (MENUVERIFY | SIZEVERIFY | REQVERIFY));
X AutoRequest(MainWindow, &Body[0], NULL, &ExitText, NULL, NULL, 258L, 100L);
X ModifyIDCMP(MainWindow, OldIDCMP);
X}
X
Xchar *CatFileComponents(dest, dirname, filename)
Xchar *dest;
Xchar *dirname;
Xchar *filename;
X{
X strcpy(dest, dirname);
X if (dirname[0] && dirname[strlen(dirname) - 1] != ':')
X strcat(dest, "/");
X strcat(dest, FileName);
X
X return dest;
X}
X
X
Xbool OpenAs(name)
Xchar *name;
X{
X struct Mand MandChunk;
X struct ILBM_info *ilbminfo, *win_read_iff();
X
X StopDrawing();
X MandChunk.MandID = 0;
X if (ilbminfo = win_read_iff(name, (short)FALSE,
X MainWindow, sizeof(MandChunk), &MandChunk)) {
X put_ea_cmap(&ilbminfo->cmap, NumColors, MandelScreen);
X InterpretMAND(&MandChunk, ilbminfo);
X }
X Saved = TRUE;
X NameValid = FALSE;
X
X return ilbminfo != NULL;
X}
X
Xbool SaveAs(name)
Xchar *name;
X{
X struct Mand MandChunk;
X unsigned char ea_colormap[3*MAXCOL];
X
X get_ea_cmap(ea_colormap, NumColors, MandelScreen);
X MakeMAND(&MandChunk);
X SuspendDrawing();
X NameValid = Saved = write_iff(name, ea_colormap, MainWindow,
X (short) 0, (short) 0, (short) TRUE, sizeof(MandChunk),
X &MandChunk);
X ResumeDrawing();
X
X return Saved;
X}
X
XSTATIC void PrjMenu(Code)
XUSHORT Code;
X{
X int SubNum = SUBNUM(Code);
X int ItemNum = ITEMNUM(Code);
X
X struct Mand MandChunk;
X char Name[DNAME_SIZE + FNAME_SIZE + 3];
X
X switch (ItemNum) {
X case PRJNEW:
X PrjNew(SubNum);
X break;
X case PRJOPN:
X if ( get_fname(MainWindow, "Select a filename to OPEN",
X FileName, DirName) == NULL )
X break;
X CatFileComponents(Name, DirName, FileName);
X OpenAs(Name);
X break;
X case PRJSVE: /* Save */
X if (NameValid) skipto prjsve;
X /* Fall Through */
X case PRJSVA: /* Save As */
X if ( get_fname(MainWindow, "Select a filename to SAVE",
X FileName, DirName) == NULL )
X break;
Xprjsve:
X CatFileComponents(Name, DirName, FileName);
X SaveAs(Name);
X break;
X case PRJSTP:
X StopDrawing();
X break;
X case PRJQUI:
X finished = TRUE;
X }
X}
X
XSTATIC void OptMenu(Code)
XUSHORT Code;
X{
X int SubNum = SUBNUM(Code);
X int ItemNum = ITEMNUM(Code);
X
X switch (ItemNum) {
X case OPTCOL:
X switch (SubNum) {
X case OCSEL:
X PenTableMode = SELECT;
X Select();
X break;
X case OCMOD:
X PenTableMode = MODULO;
X break;
X case OCRAN:
X PenTableMode = RANGES;
X break;
X case OCPAL:
X OpenColorWindow(MainWindow);
X } /* End Switch SUBNUM */
X InitPenTable();
X break;
X case OPTRES:
X switch (SubNum) {
X case ORNRM:
X PixelStep = 1;
X break;
X case OR12:
X PixelStep = 2;
X break;
X case OR13:
X PixelStep = 3;
X break;
X case OR14:
X PixelStep = 4;
X break;
X case ORFIL: /* Fill in */
X DrawPicture((bool)TRUE);
X break;
X case ORHI:
X case ORILC:
X case OREHB:
X {
X USHORT newmode = MandelNScreen.ViewModes & ~(HIRES | LACE | EXTRA_HALFBRITE);
X
X if (ItemAddress(MandelMenu, MENU(OPTMENU, OPTRES, ORHI))
X -> Flags & CHECKED)
X newmode |= HIRES;
X if (ItemAddress(MandelMenu, MENU(OPTMENU, OPTRES, ORILC))
X -> Flags & CHECKED)
X newmode |= LACE;
X if (ItemAddress(MandelMenu, MENU(OPTMENU, OPTRES, OREHB))
X -> Flags & CHECKED)
X newmode |= EXTRA_HALFBRITE;
X if (newmode != MandelNScreen.ViewModes) {
X MandelNScreen.ViewModes = newmode;
X if (Sure())
X ReInitDisplay();
X else
X UpdateOptViewResCm();
X }
X }
X break;
X case ORBCK:
X if (ItemAddress(MandelMenu, MENU(OPTMENU,OPTRES,ORBCK))->Flags & CHECKED)
X DoBorderless(MainWindow, &borderinfo);
X else
X UndoBorderless(MainWindow, &borderinfo);
X } /* End Switch SUBNUM */
X break;
X case OPTPAR:
X Parameters();
X break;
X case OPTPRI:
X switch (SubNum) {
X case OPNOR:
X SetDrawPri(0);
X break;
X case OPLOW:
X SetDrawPri(-5);
X break;
X }
X break;
X } /* End Switch ITEMNUM */
X}
X
X/*
X * This function sets the drawing function, numbered from 0.
X */
X
Xvoid SetDrawingFunction(number)
Xint number;
X{
X if (number >= 0 && number <= DF5) {
X FunctionNr = number;
X DepthFunc = DepthFuncArray[FunctionNr];
X }
X}
X
X/*
X * This function sets the i plotting function, numbered from 0.
X */
X
Xvoid SetIPlotFunction(number)
Xint number;
X{
X if (number >= 0 && number <= DIZ) {
X IPlotNr = number;
X IPlotFunc = IPlotFuncArray[IPlotNr];
X }
X}
X
X/*
X * This function sets the e plotting function, numbered from 0.
X */
X
Xvoid SetEPlotFunction(number)
Xint number;
X{
X if (number >= 0 && number <= DEZ) {
X EPlotNr = number;
X EPlotFunc = EPlotFuncArray[EPlotNr];
X }
X}
X
Xvoid DrwMenu(Code)
XUSHORT Code;
X{
X int ItemNum = ITEMNUM(Code);
X int SubNum = SUBNUM(Code);
X
X switch (ItemNum) {
X case DRWFUN:
X SetDrawingFunction(SubNum + DF1);
X break;
X case DRWIPL:
X SetIPlotFunction(SubNum + DINONE);
X break;
X case DRWEPL:
X SetEPlotFunction(SubNum + DEDEPTH);
X break;
X }
X}
X
Xvoid UnImpl()
X{
X static char alert[] = "\
X\0\144\25Mandelbrot Construction Set -- By KosmoSoft Productions\0a\
X\0\170\40Sorry, this function has not been implemented yet!\0";
X DisplayAlert(RECOVERY_ALERT, alert, 50L);
X}
X
XSTATIC USHORT OldMinWidth, OldMinHeight, OldMaxWidth, OldMaxHeight;
X
X/* Do not nest calls to DisableSizing: the original values will be lost. */
X
Xvoid DisableSizing()
X{
X OldMinWidth = MainWindow->MinWidth;
X OldMaxWidth = MainWindow->MaxWidth;
X OldMinHeight = MainWindow->MinHeight;
X OldMaxHeight = MainWindow->MaxHeight;
X WindowLimits(MainWindow, (long) MainWindow->Width, (long) MainWindow->Height,
X (long) MainWindow->Width, (long) MainWindow->Height);
X}
X
Xvoid EnableSizing()
X{
X WindowLimits(MainWindow, (long) OldMinWidth, (long) OldMinHeight,
X (long) OldMaxWidth, (long) OldMaxHeight);
X}
X
XSTATIC void PrjNew(SubNum)
XUSHORT SubNum;
X{
X struct Window *window;
X int ID;
X static double HShift = 0.0,
X VShift = 0.0;
X static double Factor = 3.0;
X double Width = RightEdge - LeftEdge,
X Height = TopEdge - BottomEdge,
X NewLeftEdge = LeftEdge,
X NewTopEdge = TopEdge,
X NewRightEdge = RightEdge,
X NewBottomEdge = BottomEdge;
X
X /* Stuff for the ABSOLUTE requester */
X
X static struct IntuiText RatioText = {
X MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 90, NULL,
X (UBYTE *) "Ratio: ", NULL };
X static struct IntuiText AbsText = {
X MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 10, NULL,
X (UBYTE *) "Select an absolute position", &RatioText };
X static struct IntuiText LRTBText[] = {
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
X (UBYTE *) "Left", NULL },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
X (UBYTE *) "Right", NULL },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
X (UBYTE *) "Top", NULL },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
X (UBYTE *) "Bottom", NULL }
X };
X static struct StringInfo LRTBinfo[] = {
X { &Buffer[0][0], &Buffer[4][0], 0, 20, 0 },
X { &Buffer[1][0], &Buffer[4][0], 0, 20, 0 },
X { &Buffer[2][0], &Buffer[4][0], 0, 20, 0 },
X { &Buffer[3][0], &Buffer[4][0], 0, 20, 0 }
X };
X static struct Gadget LRTBGadget[] = {
X { &LRTBGadget[1], 66, 30, 160, 10, /* next, LTWH */
X GADGHCOMP, /* Flags */
X RELVERIFY, /* Activation */
X STRGADGET | REQGADGET, /* GadgetType */
X (APTR) NULL, NULL, /* rendering */
X &LRTBText[0], 0, (APTR) &LRTBinfo[0], /* "Left" */
X NEGGADGETID+1, NULL },
X { &LRTBGadget[2], 66, 45, 160, 10, /* next, LTWH */
X GADGHCOMP,
X RELVERIFY,
X STRGADGET | REQGADGET,
X (APTR) NULL, NULL,
X &LRTBText[1], 0, (APTR) &LRTBinfo[1], /* Right */
X NEGGADGETID+1, NULL },
X { &LRTBGadget[3], 66, 60, 160, 10, /* next, LTWH */
X GADGHCOMP,
X RELVERIFY,
X STRGADGET | REQGADGET,
X (APTR) NULL, NULL,
X &LRTBText[2], 0, (APTR) &LRTBinfo[2], /* Top */
X NEGGADGETID+1, NULL },
X { NULL, 66, 75, 160, 10, /* next, LTWH */
X GADGHCOMP,
X RELVERIFY,
X STRGADGET | REQGADGET,
X (APTR) NULL, NULL,
X &LRTBText[3], 0, (APTR) &LRTBinfo[3], /* Bottom */
X NEGGADGETID+1, NULL }
X };
X static struct Requester AbsRequest = {
X NULL, 25, 40, 260, 130, 0,0, &PositiveGadget, NULL,
X &AbsText, 0, 1 };
X
X /* Stuff for the SHIFT requester */
X
X static struct IntuiText ShiftText = {
X MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 10, NULL,
X (UBYTE *) "Select a window shift amount", NULL };
X static struct IntuiText RDText[] = {
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
X (UBYTE *) "Right", NULL },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
X (UBYTE *) "Down", NULL }
X };
X static struct Gadget RDGadget[] = {
X { &RDGadget[1], 66, 45, 160, 10, /* next, LTWH */
X GADGHCOMP,
X 0,
X STRGADGET | REQGADGET,
X (APTR) NULL, NULL,
X &RDText[0], 0, (APTR) &LRTBinfo[0], /* Right */
X 0, NULL },
X { NULL, 66, 60, 160, 10, /* next, LTWH */
X GADGHCOMP,
X 0,
X STRGADGET | REQGADGET,
X (APTR) NULL, NULL,
X &RDText[1], 0, (APTR) &LRTBinfo[1], /* Down */
X 0, NULL }
X };
X static struct Requester ShiftRequest = {
X NULL, 25, 40, 260, 130, 0,0, &PositiveGadget, NULL,
X &ShiftText, 0, 1 };
X
X /* Stuff for the ZOOM requester */
X
X static struct IntuiText ZoomText = {
X MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 10, NULL,
X (UBYTE *) "Select a zoom center", NULL };
X static struct IntuiText RIFText[] = {
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
X (UBYTE *) "X:Real", NULL },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
X (UBYTE *) "Y:Imag", NULL },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
X (UBYTE *) "Factor", NULL }
X };
X static struct Gadget RIFGadget[] = {
X { &RIFGadget[1], 66, 30, 160, 10, /* next, LTWH */
X GADGHCOMP,
X 0,
X STRGADGET | REQGADGET,
X (APTR) NULL, NULL,
X &RIFText[0], 0, (APTR) &LRTBinfo[0], /* Re */
X 0, NULL },
X { &RIFGadget[2], 66, 45, 160, 10, /* next, LTWH */
X GADGHCOMP,
X 0,
X STRGADGET | REQGADGET,
X (APTR) NULL, NULL,
X &RIFText[1], 0, (APTR) &LRTBinfo[1], /* Im */
X 0, NULL },
X { NULL, 66, 60, 160, 10, /* next, LTWH */
X GADGHCOMP,
X 0,
X STRGADGET | REQGADGET,
X (APTR) NULL, NULL,
X &RIFText[2], 0, (APTR) &LRTBinfo[2], /* Factor */
X 0, NULL }
X };
X static struct Requester ZoomRequest = {
X NULL, 25, 40, 260, 130, 0,0, &PositiveGadget, NULL,
X &ZoomText, 0, 1 };
X
X switch (SubNum) {
X case PNRED:
X if (MouseStatus != FLASHING) return;
X else {
X register SHORT w = MainWindow -> GZZWidth,
X h = MainWindow -> GZZHeight;
X register SHORT X1, Y1, X2, Y2;
X
X /* If you cast less, Aztec seems to do it wrong... */
X X1 = (-(long)FrameX1 * w) / ((long)FrameX2 - (long)FrameX1);
X Y1 = (-(long)FrameY1 * h) / ((long)FrameY2 - (long)FrameY1);
X X2 = ((long)(w-1-FrameX1) * w) / ((long)FrameX2 - (long)FrameX1)
X - 1;
X Y2 = ((long)(h-1-FrameY1) * h) / ((long)FrameY2 - (long)FrameY1)
X - 1;
X
X NewLeftEdge = LeftEdge + X1 * CXStep;
X NewRightEdge = LeftEdge + X2 * CXStep;
X NewTopEdge = TopEdge - Y1 * CYStep;
X NewBottomEdge = TopEdge - Y2 * CYStep;
X
X skipto pnabs;
X }
X case PNENL:
X if (MouseStatus != FLASHING) return;
X
X NewLeftEdge = LeftEdge + FrameX1 * CXStep;
X NewRightEdge = LeftEdge + FrameX2 * CXStep;
X NewTopEdge = TopEdge - FrameY1 * CYStep;
X NewBottomEdge = TopEdge - FrameY2 * CYStep;
X skipto pnabs;
X case PNSHF:
X NegativeGadget.NextGadget = &RDGadget[0];
X do {
X sprintf(Buffer[0], "%1.6g",HShift);
X sprintf(Buffer[1], "%1.6g",VShift);
X
X window = MyRequest(&ShiftRequest, MainWindow);
X ID = WaitMyRequest(window);
X EndMyRequest(&ShiftRequest, window, MainWindow);
X if (ID == NEGGADGETID) return;
X
X } while (sscanf(Buffer[0], "%lf", &HShift)+
X sscanf(Buffer[1], "%lf", &VShift) != 2);
X
X NewLeftEdge = LeftEdge + HShift * Width;
X NewRightEdge = RightEdge + HShift * Width;
X NewTopEdge = TopEdge - VShift * Height;
X NewBottomEdge = BottomEdge - VShift * Height;
X
X skipto pnabs;
X case PNZI:
X case PNZO: {
X double ReMid, ImMid;
X
X if (MouseStatus == NOTFRAMING) {
X ReMid = (RightEdge + LeftEdge) / 2.0;
X ImMid = (TopEdge + BottomEdge) / 2.0;
X } else {
X ReMid = ReMouse;
X ImMid = ImMouse;
X }
X
X NegativeGadget.NextGadget = &RIFGadget[0];
X do {
X sprintf(Buffer[0], "%1.6g",ReMid);
X sprintf(Buffer[1], "%1.6g",ImMid);
X sprintf(Buffer[2], "%1.6g",Factor);
X
X window = MyRequest(&ZoomRequest, MainWindow);
X ID = WaitMyRequest(window);
X EndMyRequest(&ZoomRequest, window, MainWindow);
X if (ID == NEGGADGETID) return;
X
X } while (sscanf(Buffer[0], "%lf", &ReMid)+
X sscanf(Buffer[1], "%lf", &ImMid)+
X sscanf(Buffer[2], "%lf", &Factor) != 3);
X if (SubNum == PNZI) {
X if (Factor == 0.0) {
X Factor = 1.0;
X }
X Width /= Factor;
X Height /= Factor;
X } else {
X Width *= Factor;
X Height *= Factor;
X }
X NewLeftEdge = ReMid - Width / 2.0;
X NewTopEdge = ImMid + Height / 2.0;
X NewRightEdge = NewLeftEdge + Width;
X NewBottomEdge = NewTopEdge - Height;
X skipto pnabs;
X }
X case PNABS:
X NewLeftEdge = LeftEdge;
X NewRightEdge = RightEdge;
X NewTopEdge = TopEdge;
X NewBottomEdge = BottomEdge;
X
Xpnabs:
X NegativeGadget.NextGadget = &LRTBGadget[0];
X sprintf(Buffer[0], "%1.10g", NewLeftEdge);
X sprintf(Buffer[1], "%1.10g", NewRightEdge);
X sprintf(Buffer[2], "%1.10g", NewTopEdge);
X sprintf(Buffer[3], "%1.10g", NewBottomEdge);
X sprintf(RatioText.IText+7, "%1.4f ", Ratio(NewLeftEdge,
X NewRightEdge, NewTopEdge, NewBottomEdge, MainWindow));
X
X do {
X window = MyRequest(&AbsRequest, MainWindow);
X
X while ( (ID = WaitMyRequest(window) ) > NEGGADGETID) {
X sscanf(Buffer[0], "%lf", &NewLeftEdge);
X sscanf(Buffer[1], "%lf", &NewRightEdge);
X sscanf(Buffer[2], "%lf", &NewTopEdge);
X sscanf(Buffer[3], "%lf", &NewBottomEdge);
X sprintf(RatioText.IText+7, "%1.4f ",
X Ratio(NewLeftEdge, NewRightEdge, NewTopEdge,
X NewBottomEdge, MainWindow));
X
X PrintIText(AbsRequest.ReqLayer->rp, &RatioText, 0L, 0L);
X }
X
X EndMyRequest(&AbsRequest, window, MainWindow);
X
X } while (sscanf(Buffer[0], "%lf", &NewLeftEdge)+
X sscanf(Buffer[1], "%lf", &NewRightEdge)+
X sscanf(Buffer[2], "%lf", &NewTopEdge)+
X sscanf(Buffer[3], "%lf", &NewBottomEdge) < 4);
X
X if (ID != POSGADGETID) return;
X
X LeftEdge = NewLeftEdge;
X RightEdge = NewRightEdge;
X TopEdge = NewTopEdge;
X BottomEdge = NewBottomEdge;
X
X StopFraming();
X StopDrawing();
X
X break;
X }
X DrawPicture((bool)FALSE); /* Don't fill in */
X}
X
Xfloat Ratio(l, r, t, b, window)
Xdouble l, r, t, b;
Xstruct Window *window;
X{
X float PixelRatio;
X float ReImRatio;
X
X if (t == b) t = b+1; /* You never know... */
X
X PixelRatio = (float) window->GZZWidth / window->GZZHeight;
X
X if (window->WScreen->ViewPort.Modes & HIRES) PixelRatio /= 2;
X if (window->WScreen->ViewPort.Modes & LACE) PixelRatio *= 2;
X ReImRatio = (r - l)/(t - b);
X
X return ReImRatio / PixelRatio;
X}
X
Xvoid Parameters()
X{
X struct Window *window;
X int ID;
X int NewMaxDepth, NewRangeWidth, NewWBwidth, NewWBheight;
X
X static struct IntuiText ParamText = {
X MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 10, NULL,
X (UBYTE *) "Select these parameters", NULL };
X static struct IntuiText ParmText[] = {
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -120, 0, NULL,
X (UBYTE *) "Max depth", NULL },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -120, 0, NULL,
X (UBYTE *) "Range width", NULL },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -120, 0, NULL,
X (UBYTE *) "Screen width", NULL },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -120, 0, NULL,
X (UBYTE *) "Screen height", NULL }
X };
X static struct StringInfo Parminfo[] = {
X { &Buffer[0][0], &Buffer[4][0], 0, 20, 0 },
X { &Buffer[1][0], &Buffer[4][0], 0, 20, 0 },
X { &Buffer[2][0], &Buffer[4][0], 0, 20, 0 },
X { &Buffer[3][0], &Buffer[4][0], 0, 20, 0 }
X };
X static struct Gadget ParmGadget[] = {
X { &ParmGadget[1], 130, 30, 96, 10, /* next, LTWH */
X GADGHCOMP, /* Flags */
X RELVERIFY | LONGINT, /* Activation */
X STRGADGET | REQGADGET, /* GadgetType */
X (APTR) NULL, NULL, /* rendering */
X &ParmText[0], 0, (APTR) &Parminfo[0], /* "MaxDepth" */
X 0, NULL },
X { &ParmGadget[2], 130, 45, 96, 10, /* next, LTWH */
X GADGHCOMP,
X RELVERIFY | LONGINT,
X STRGADGET | REQGADGET,
X (APTR) NULL, NULL,
X &ParmText[1], 0, (APTR) &Parminfo[1], /* "RangeWidth" */
X 0, NULL },
X { &ParmGadget[3], 130, 60, 96, 10, /* next, LTWH */
X GADGHCOMP,
X RELVERIFY | LONGINT,
X STRGADGET | REQGADGET,
X (APTR) NULL, NULL,
X &ParmText[2], 0, (APTR) &Parminfo[2], /* "Screen width" */
X 0, NULL },
X { NULL, 130, 75, 96, 10, /* next, LTWH */
X GADGHCOMP,
X RELVERIFY | LONGINT,
X STRGADGET | REQGADGET,
X (APTR) NULL, NULL,
X &ParmText[3], 0, (APTR) &Parminfo[3], /* "Screen height" */
X 0, NULL }
X };
X static struct Requester ParmRequest = {
X NULL, 25, 40, 260, 130, 0,0, &PositiveGadget, NULL,
X &ParamText, 0, 1 };
X
X /* Stuff for the PARAMETERS requester */
X NegativeGadget.NextGadget = &ParmGadget[0];
X Parminfo[0].LongInt = MaxDepth;
X Parminfo[1].LongInt = RangeWidth;
X Parminfo[2].LongInt = WBWidth;
X Parminfo[3].LongInt = WBHeight;
X do {
X sprintf(Buffer[0], "%ld", Parminfo[0].LongInt);
X sprintf(Buffer[1], "%ld", Parminfo[1].LongInt);
X sprintf(Buffer[2], "%ld", Parminfo[2].LongInt);
X sprintf(Buffer[3], "%ld", Parminfo[3].LongInt);
X
X window = MyRequest(&ParmRequest, MainWindow);
X ID = WaitMyRequest(window);
X EndMyRequest(&ParmRequest, window, MainWindow);
X if (ID == NEGGADGETID) return;
X
X NewMaxDepth = Parminfo[0].LongInt;
X NewRangeWidth = Parminfo[1].LongInt;
X NewWBwidth = Parminfo[2].LongInt;
X NewWBheight = Parminfo[3].LongInt;
X } while ( NewMaxDepth < 0 || NewMaxDepth > MAXDEPTH ||
X NewRangeWidth < 0 || NewRangeWidth > MAXDEPTH );
X
X if (NewRangeWidth != RangeWidth) InitPenTable();
X MaxDepth = NewMaxDepth;
X RangeWidth = NewRangeWidth;
X
X if ((NewWBwidth != WBWidth || NewWBheight != WBHeight) && Sure()) {
X WBWidth = NewWBwidth;
X WBHeight = NewWBheight;
X ReInitDisplay();
X }
X}
X
Xvoid UpdateCheckmarks()
X{
X UpdateOptColorCm();
X UpdateOptDrawResCm();
X UpdateOptViewResCm();
X UpdateOptPriCm();
X UpdateDrwCm();
X}
X
Xvoid UpdateOptColorCm()
X{
X SelectMenu(MENU(OPTMENU, OPTCOL, OCSEL), (bool)(PenTableMode == SELECT));
X SelectMenu(MENU(OPTMENU, OPTCOL, OCMOD), (bool)(PenTableMode == MODULO));
X SelectMenu(MENU(OPTMENU, OPTCOL, OCRAN), (bool)(PenTableMode == RANGES));
X}
X
Xvoid UpdateOptDrawResCm()
X{
X SelectMenu(MENU(OPTMENU, OPTRES, ORNRM), (bool)(PixelStep == 1));
X SelectMenu(MENU(OPTMENU, OPTRES, OR12 ), (bool)(PixelStep == 2));
X SelectMenu(MENU(OPTMENU, OPTRES, OR13 ), (bool)(PixelStep == 3));
X SelectMenu(MENU(OPTMENU, OPTRES, OR14 ), (bool)(PixelStep == 4));
X}
X
Xvoid UpdateOptViewResCm()
X{
X SelectMenu(MENU(OPTMENU, OPTRES, ORHI ),
X (bool)((MandelNScreen.ViewModes & HIRES) != 0));
X SelectMenu(MENU(OPTMENU, OPTRES, ORILC),
X (bool)((MandelNScreen.ViewModes & LACE) != 0));
X SelectMenu(MENU(OPTMENU, OPTRES, OREHB),
X (bool)((MandelNScreen.ViewModes & EXTRA_HALFBRITE) != 0));
X SelectMenu(MENU(OPTMENU, OPTRES, ORBCK),
X (bool)((MainWindow->Flags & BORDERLESS) != 0));
X}
X
Xvoid UpdateOptPriCm()
X{
X SelectMenu(MENU(OPTMENU, OPTPRI, OPNOR), (bool)(DrawPri == 0));
X SelectMenu(MENU(OPTMENU, OPTPRI, OPLOW), (bool)(DrawPri < 0));
X}
X
Xvoid UpdateFunCm()
X{
X SelectMenu(MENU(DRWMENU, DRWFUN, DF1), (bool)(FunctionNr == DF1-DF1));
X SelectMenu(MENU(DRWMENU, DRWFUN, DF2), (bool)(FunctionNr == DF2-DF1));
X SelectMenu(MENU(DRWMENU, DRWFUN, DF3), (bool)(FunctionNr == DF3-DF1));
X SelectMenu(MENU(DRWMENU, DRWFUN, DFUPF), (bool)(FunctionNr == DFUPF-DF1));
X SelectMenu(MENU(DRWMENU, DRWFUN, DF5), (bool)(FunctionNr == DF5-DF1));
X}
X
Xvoid UpdateIPlotCm()
X{
X SelectMenu(MENU(DRWMENU, DRWIPL, DINONE), (bool)(IPlotNr == DINONE-DINONE));
X SelectMenu(MENU(DRWMENU, DRWIPL, DIZ) , (bool)(IPlotNr == DIZ-DINONE));
X}
X
Xvoid UpdateEPlotCm()
X{
X SelectMenu(MENU(DRWMENU, DRWEPL, DEDEPTH), (bool)(EPlotNr == DEDEPTH-DEDEPTH));
X SelectMenu(MENU(DRWMENU, DRWEPL, DEZ) , (bool)(EPlotNr == DEZ-DEDEPTH));
X}
X
Xvoid UpdateDrwCm()
X{
X UpdateFunCm();
X UpdateIPlotCm();
X UpdateEPlotCm();
X}
SHAR_EOF
echo "extracting Jiff.c"
sed 's/^X//' << \SHAR_EOF > Jiff.c
X
X/*
X * JIFF.H
X */
X
X#define XMAX 640
X#define LOXMAX 320
X#define YMAX 200
X#define XASPECT 5
X#define YASPECT 11
X
X/*
X * EA handy make a long from 4 chars macros redone to work with Aztec
X */
X#define MAKE_ID(a, b, c, d)\
X( ((long)(a)<<24) | ((long)(b)<<16) | ((long)(c)<<8) | (long)(d) )
X
X/*
X * These are the IFF types I deal with
X */
X#define FORM MAKE_ID('F', 'O', 'R', 'M')
X#define ILBM MAKE_ID('I', 'L', 'B', 'M')
X#define BMHD MAKE_ID('B', 'M', 'H', 'D')
X#define CMAP MAKE_ID('C', 'M', 'A', 'P')
X#define BODY MAKE_ID('B', 'O', 'D', 'Y')
X
X/*
X * And these are the IFF types I ignore but don't squawk about
X */
X#define GRAB MAKE_ID('G', 'R', 'A', 'B')
X#define DEST MAKE_ID('D', 'E', 'S', 'T')
X#define SPRT MAKE_ID('S', 'P', 'R', 'T')
X#define CAMG MAKE_ID('C', 'A', 'M', 'G')
X#define CRNG MAKE_ID('C', 'R', 'N', 'G')
X#define CCRT MAKE_ID('C', 'C', 'R', 'T')
X
X#define EVEN(x) (((x) + 1) & ~1)
X#define MANDEL
X
X/*
X * Some macros for raster memory allocation ... redefine if you're
X * sensible and manage memory locally
X */
X
X#ifndef MANDEL
X
X/*
X * ralloc - raster alloc
X */
X# define ralloc(amount) (PLANEPTR)AllocMem((long)(amount), MEMF_CHIP)
X/*
X * rfree - raster free
X */
X# define rfree(pt, amount) FreeMem( (pt), (long)(amount) )
X
X#else /* MANDEL */
X
X# include <mandel.h>
X
X/*
X * We don't want to allocate a complete raster for the picture, since we
X * already have a screen with a window where we want to have it.
X * Therefore, we allocate some small buffers, which get blitted into our
X * window as soon as they fill up.
X */
X# define MAXPLANESIZE 1040L
X/*
X * ralloc - raster alloc
X */
X# define ralloc(amount) (PLANEPTR)AllocMem(MAXPLANESIZE, MEMF_CHIP | MEMF_CLEAR)
X/*
X * rfree - raster free
X */
X# define rfree(pt, amount) FreeMem( (pt), MAXPLANESIZE )
X
X#endif /* !MANDEL */
X
X/*
X * line_bytes = the number of words * 2 (for bytes) a raster line takes up
X */
X#define line_bytes(width) ((((width) + 15) >> 3) & ~0x0001)
X
X/*
X * psize - plane size in bytes (an even number) of a raster given width
X * and height
X */
X#define psize(width, height) ( line_bytes(width)*height)
X
X/*
X * The place to throw excess bits
X */
X#define bit_bucket(file, length) fseek(file, (long)EVEN(length), 1)
X
X
Xunion bytes4 {
X char b4_name[4];
X LONG b4_type;
X};
X
Xstruct iff_chunk {
X union bytes4 iff_type;
X LONG iff_length;
X};
X
Xstruct form_chunk {
X union bytes4 fc_type; /* == FORM */
X LONG fc_length;
X union bytes4 fc_subtype;
X};
X
Xstruct CommodoreAmiga {
X struct iff_chunk camg_iffc; /* == CAMG */
X LONG camg_data;
X};
X
X#ifndef MANDEL /* We have this already in Mandel.h */
Xstruct BitMapHeader {
X UWORD w,
X h;
X UWORD x,
X y;
X UBYTE nPlanes;
X UBYTE masking;
X UBYTE compression;
X UBYTE pad1;
X UWORD transparentColor;
X UBYTE xAspect,
X yAspect;
X WORD pageWidth,
X pageHeight;
X};
X
X/*
X * ILBM_info is the structure win_read_iff returns, and is hopefully all
X * you need to deal with out of the iff reader routines below
X */
Xstruct ILBM_info {
X struct BitMapHeader header;
X UBYTE cmap[MAXCOL * 3];
X struct BitMap bitmap;
X#ifdef MANDEL
X struct Mand *mand;
X long mandsize;
X#endif
X};
X
X#endif /* !MANDEL */
X
X/*-
X * I sure wish C function "prototypes" were real and not just ANSI
X *
X * extern struct ILBM_info *win_read_iff();
X * win_read_iff( char *filename, short just_colors, int MandSize,
X * APTR MandPointer );
X * extern void free_planes(); free_planes( struct BitMap *bitmap);
X * extern int write_iff();
X * write_iff(char *name, unsigned char *colors, struct Window *window,
X * short xoff, short yoff, short compressed);
X */
X
X/*
X * Anyone know where some useful minterms are defined?
X */
X#define COPY_MINTERM 0x0C0L
X
X/***
X
X A meditation for the guru from the Diamond Sutra -
X
X So shall you think of all this fleeting world:
X A star at dawn, a bubble in a stream;
X A flash of lightning in a summer cloud,
X A flickering lamp, a phantom, and a dream.
X
X***/
X
X
X/*
X * jiff.c Jim Kent's iff - ilbm reader
X *
X * This is the (sortof) short (sortof) simple no-frills IFF reader to get
X * something out of DPaint, Images, or the Animator. It works well with
X * the Aztec C compiler. It should work with Lattice but you never know
X * until you try it. I haven't.
X *
X * I've included a simple main program. This is just to make it stand alone.
X * Since amiga screen initializations are massive, all it does as is is
X * read it into a BitMap, and then free up the BitMap. Should crash it if
X * it's gonna crash though.
X *
X * The main interface to this is through the routine win_read_iff(filename).
X * This returns a ILBM_info structure-pointer on success, and NULL on
X * failure. It cleans up after itself on failure.
X *
X * I hope you will find this useful and easy to use. Please forgive my funky
X * indentation style? Well at least I'm consistent! (* Run through the
X * C-Beautifier by Olaf Seibert !! *)
X *
X * To demonstrate what a nice guy I am even though I'm far from wild about
X * the IFF standard I'm placing this in the public domain. When you
X * remove the DEBUG and PARANOID definitions the code is only 1536 bytes
X * long.
X *
X * -Jim Kent April 22, 1986
X */
X
X
X#include <stdio.h>
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <graphics/gfx.h>
X#include <libraries/dos.h>
X#include <intuition/intuition.h>
X/* #include "jiff.h" */
X
X
X/*
X * This is an all too common state of software development. Get rid of
X * this define as soon as it runs.
X */
X#undef DEBUG
X/* #define DEBUG/* */
X
X/*
X * This is the normal state of software development. Seriously undefine
X * this to make it shut up about errors and reduce code size half way
X * through beta testing...
X */
X#undef PARANOID
X
X/*
X * This is nice if you want to use a debugger on the STATIC data and
X * routines in this file. Redefine only if you don't need a debugger.
X */
X
X#ifdef DEBUG
X# undef STATIC
X# define STATIC
X#endif
X
XSTATIC struct ILBM_info *win_read_ilbm();
XSTATIC struct ILBM_info *win_read_body();
X
X/*
X * OK this code is almost re-entrant. Pass this guy from above to make it
X * really re-entrant. (Why do you need a reentrant ILBM reader though??
X * Maybe for Dale ... ) Well, look in the IFF specs for instance... [Olaf
X * Seibert, KosmoSoft]
X */
XSTATIC struct ILBM_info root_info; /* static so get initialized to
X * zero */
X
X
X#ifdef PARANOID
X/*
X * a little paranoid routine that say's where we got before EOF
X */
XSTATIC void
Xiff_truncated(where)
Xint where;
X{
X printf("ILBM truncated %d\n", where);
X free_planes(&root_info.bitmap);
X}
X
X#endif PARANOID
X
X
Xstruct ILBM_info *
Xwin_read_iff(name, just_colors, window, MandSize, MandPointer)
Xchar *name;
Xshort just_colors;
Xstruct Window *window;
Xint MandSize;
XAPTR MandPointer;
X{
X struct ILBM_info *info = &root_info;
X FILE *file;
X struct form_chunk chunk;
X
X if ((file = fopen(name, "r")) == 0) {
X#ifdef PARANOID
X printf("couldn't fopen %s to read\n", name);
X#endif PARANOID
X return NULL;
X }
X if (fread(&chunk, sizeof (struct form_chunk), 1, file) != 1) {
X#ifdef PARANOID
X iff_truncated(0);
X#endif PARANOID
X fclose(file);
X return NULL;
X }
X if (chunk.fc_type.b4_type != FORM) {
X#ifdef PARANOID
X printf("not a FORM - %s\n", name);
X#endif PARANOID
X fclose(file);
X return NULL;
X }
X if (chunk.fc_subtype.b4_type != ILBM) {
X#ifdef PARANOID
X printf("FORM not an ILBM - %s\n", name);
X#endif PARANOID
X fclose(file);
X return NULL;
X }
X#ifdef DEBUG
X printf("FORM %ld ILBM\n", chunk.fc_length);
X#endif DEBUG
X
X#ifdef MANDEL
X info->mand = (struct Mand *) MandPointer;
X info->mandsize = MandSize;
X info->mand->MandID = 0; /* we have not yet read it */
X#endif
X
X info = win_read_ilbm(file, info, chunk.fc_length - sizeof (chunk),
X just_colors, window);
X#ifdef DEBUG
X printf("info = %lx\n", info);
X#endif DEBUG
X
X#ifdef MANDEL
X /*
X * Backward compatibility with non-standard code: We may want to read
X * the extra MAND if we have not read it by now.
X */
X if (info && MandSize && info->mand->MandID != MAND) {
X fread(MandPointer, 1, MandSize, file);
X info->mand->Size -= 2 * sizeof (long); /* patch bug */
X }
X#endif MANDEL
X
X fclose(file);
X
X return info;
X}
X
XSTATIC struct ILBM_info *
Xwin_read_ilbm(file, info, length, just_colors, window)
XFILE *file;
Xstruct ILBM_info *info;
Xlong length;
Xshort just_colors;
Xstruct Window *window;
X{
X struct iff_chunk chunk;
X int i;
X long read_in = 0;
X int got_header = FALSE; /* To make sure gots the header
X * first */
X int got_cmap = FALSE; /* Make sure get cmap before
X * "BODY" */
X
X /*
X * Make sure the Planes are all NULL so can free up memory easily on
X * error abort
X */
X for (i = 0; i < 8; i++)
X info->bitmap.Planes[i] = NULL;
X
X while (read_in < length) {
X if (fread(&chunk, sizeof (chunk), 1, file) != 1) {
X#ifdef PARANOID
X iff_truncated(1);
X#endif PARANOID
X return NULL;
X }
X switch (chunk.iff_type.b4_type) {
X case BMHD:
X#ifdef DEBUG
X printf("\tBMHD %ld\n", chunk.iff_length);
X#endif DEBUG
X if (fread(&info->header, sizeof (info->header), 1, file) != 1) {
X#ifdef PARANOID
X iff_truncated(2);
X#endif PARANOID
X return NULL;
X }
X got_header = TRUE;
X break;
X case CMAP:
X#ifdef DEBUG
X printf("\tCMAP %ld\n", chunk.iff_length);
X#endif DEBUG
X if (!got_header) {
X#ifdef PARANOID
X printf("CMAP before BMHD\n");
X#endif PARANOID
X return NULL;
X }
X if (chunk.iff_length <= 3 * MAXCOL) {
X if (fread(info->cmap, (int) chunk.iff_length, 1, file) != 1) {
X#ifdef PARANOID
X iff_truncated(3);
X#endif PARANOID
X return NULL;
X }
X } else {
X#ifdef PARANOID
X printf("warning, more than %d colors in ILBM CMAP\n",
X MAXCOL);
X#endif PARANOID
X if (fread(info->cmap, (int) 3 * MAXCOL, 1, file) != 1) {
X#ifdef PARANOID
X iff_truncated(4);
X#endif PARANOID
X return NULL;
X }
X bit_bucket(file, chunk.iff_length - 3 * MAXCOL);
X }
X got_cmap = TRUE;
X if (just_colors)
X return info;
X break;
X case MAND:
X#ifdef DEBUG
X printf("\tMAND %ld\n", chunk.iff_length);
X#endif DEBUG
X if (chunk.iff_length + sizeof (chunk) <= info->mandsize) {
X if (fread((char *) info->mand + sizeof (chunk),
X (int) chunk.iff_length, 1, file) != 1) {
X#ifdef DEBUG
X printf("fread MAND fails; filepos %ld ferror %d\n",
X (long) ftell(file), (int) ferror(file));
X#endif
X return NULL;
X }
X *(struct iff_chunk *) info->mand = chunk;
X
X /*
X * skip padding byte
X */
X if (chunk.iff_length & 1)
X getc(file);
X } else {
X#ifdef DEBUG
X printf("skipping MAND; too large for buffer (%ld)\n",
X (long) info->mandsize);
X#endif
X bit_bucket(file, chunk.iff_length);
X }
X break;
X case BODY:
X if (!got_cmap) {
X#ifdef PARANOID
X printf("BODY before CMAP\n");
X#endif PARANOID
X return NULL;
X }
X#ifdef DEBUG
X printf("\tBODY %ld\n", chunk.iff_length);
X#endif DEBUG
X return win_read_body(file, info, chunk.iff_length, window);
X
X default: /* Squawk about unknown types if PARANOID */
X#ifdef PARANOID
X printf("\t unknown type %lx of b4_type\n", chunk.iff_type.b4_type);
X case GRAB: /* Ignore documented but unwanted types */
X case DEST:
X case SPRT:
X case CAMG:
X case CRNG:
X case CCRT:
X#endif PARANOID
X bit_bucket(file, chunk.iff_length);
X break;
X }
X read_in += EVEN(chunk.iff_length) + sizeof (chunk);
X }
X#ifdef PARANOID
X printf("no BODY in ILBM\n");
X#endif PARANOID
X return NULL;
X}
X
X
X
XSTATIC struct ILBM_info *
Xwin_read_body(file, info, length, window)
XFILE *file;
Xregister struct ILBM_info *info;
Xlong length;
Xstruct Window *window;
X{
X struct ILBM_header *header;
X struct BitMap *bm;
X int i,
X j;
X int rlength;
X int plane_offset;
X ULONG YSize,
X DestX,
X DestY;
X
X#ifdef DEBUG
X printf("win_read_body( %lx %lx %ld)\n", file, info, length);
X#endif DEBUG
X
X#ifdef PARANOID
X /*
X * When paranoid do a little error checking first ... fail fast!
X */
X if (info->header.nPlanes > 8) {
X printf("Whoa, woe Dale only speaks 8 planes boy, not %d\n",
X info->header.nPlanes);
X return NULL;
X }
X#endif PARANOID
X
X /*
X * Ok a little more error checking
X */
X if (info->header.compression != 0 && info->header.compression != 1) {
X#ifdef PARANOID
X printf("unrecognized compression type %d\n", info->header.compression);
X#endif PARANOID
X return NULL;
X }
X /*
X * Set up the bitmap part that doesn't involve memory allocation first
X * - hey this part does get done, and let's be optimistic...
X */
X info->bitmap.BytesPerRow = line_bytes(info->header.w);
X info->bitmap.Rows = info->header.h;
X info->bitmap.Depth = info->header.nPlanes;
X info->bitmap.Flags = info->bitmap.pad = 0;
X
X rlength = info->bitmap.Rows * info->bitmap.BytesPerRow;
X
X for (i = 0; i < info->header.nPlanes; i++) {
X if ((info->bitmap.Planes[i] = ralloc(rlength)) == NULL) {
X#ifdef PARANOID
X printf("couldn't alloc plane %d in win_read_body\n", i);
X#endif PARANOID
X free_planes(&info->bitmap);
X return NULL;
X }
X }
X
X plane_offset = 0;
X YSize = (MAXPLANESIZE / info->bitmap.BytesPerRow);
X if (window->Flags & GIMMEZEROZERO) {
X DestX = 0;
X DestY = 0;
X } else {
X DestX = window->BorderLeft;
X DestY = window->BorderTop;
X }
X
X for (i = 0; i < info->bitmap.Rows; i++) {
X /*
X * This test should be in the inner loop for shortest code, in the
X * outer loop for greatest speed, so sue me I compromised
X */
X if (info->header.compression == 0) {
X for (j = 0; j < info->bitmap.Depth; j++) {
X if (fread(info->bitmap.Planes[j] + plane_offset,
X info->bitmap.BytesPerRow, 1, file) != 1) {
X#ifdef PARANOID
X iff_truncated(6);
X#endif PARANOID
X free_planes(&info->bitmap);
X return NULL;
X }
X }
X } else {
X register char *dest,
X value;
X register int so_far,
X count; /* How much have unpacked so far */
X
X for (j = 0; j < info->bitmap.Depth; j++) {
X so_far = info->bitmap.BytesPerRow;
X dest = (char *) info->bitmap.Planes[j] + plane_offset;
X while (so_far > 0) {
X if ((value = getc(file)) == 128) {
X#ifdef DEBUG
X printf("NOP\n");
X#endif DEBUG
X } else if (value > 0) {
X count = (int) value + 1;
X so_far -= count;
X if (fread(dest, count, 1, file) != 1) {
X#ifdef PARANOID
X iff_truncated(7);
X#endif PARANOID
X free_planes(&info->bitmap);
X return NULL;
X }
X dest += count;
X } else {
X count = (int) -value + 1;
X so_far -= count;
X value = getc(file);
X while (--count >= 0) /* This is fastest loop on
X * the 68000 */
X *dest++ = value;
X }
X }
X if (so_far != 0) {
X#ifdef PARANOID
X printf("compression quite screwed up, aborting %d\n", so_far);
X#endif PARANOID
X free_planes(&info->bitmap);
X return NULL;
X }
X }
X }
X plane_offset += info->bitmap.BytesPerRow;
X
X if (plane_offset > MAXPLANESIZE - info->bitmap.BytesPerRow) {
X BltBitMapRastPort(&info->bitmap, 0L, 0L,
X window->RPort, DestX, DestY,
X info->bitmap.BytesPerRow * 8L, YSize,
X COPY_MINTERM);
X plane_offset = 0;
X DestY += YSize;
X }
X }
X
X if (plane_offset) {
X BltBitMapRastPort(&info->bitmap, 0L, 0L,
X window->RPort, DestX, DestY,
X info->bitmap.BytesPerRow * 8L,
X (long) plane_offset / info->bitmap.BytesPerRow,
X COPY_MINTERM);
X }
X if (length & 1) {
X /*
X * Skip padding byte
X */
X getc(file);
X }
X free_planes(&info->bitmap);
X return info;
X}
X
X
Xvoid
Xfree_planes(bmap)
Xregister struct BitMap *bmap;
X{
X PLANEPTR plane;
X long length;
X short i;
X
X length = bmap->BytesPerRow * bmap->Rows;
X
X for (i = bmap->Depth; --i >= 0;) {
X if ((plane = bmap->Planes[i]) != NULL) {
X rfree(plane, length);
X bmap->Planes[i] = NULL;
X }
X }
X}
X
X
X
X
X
X
X#undef DEBUG
X/* #define DEBUG/* */
X#undef PARANOID
X
X/*----------------------------------------------------------------------*
X * jpacker.c Convert data to "cmpByteRun1" run compression.
X *
X * pack_row() is an adaptation of PackRow()
X * by Jerry Morrison and Steve Shaw, Electronic Arts,
X * modified and tweaked by Jim Kent, Dancing Flame 05/02/86
X *
X * control bytes:
X * [0..127] : followed by n+1 bytes of data.
X * [-1..-127] : followed by byte to be repeated(-n)+1 times.
X * -128 : NOOP.
X *
X *
X * write_iff() is the only function you can access in this module.
X *----------------------------------------------------------------------*/
X
X/*-
X#include <exec/types.h>
X#include <graphics/gfx.h>
X#include <stdio.h>
X#include "jiff.h"
X*/
X
X#define DUMP 0
X#define RUN 1
X
X#define MINRUN 3
X#define MAXRUN 128
X#define MAXDAT 128
X
X/*
X * pack_row - pass source line pointer, length of line, and file. Returns
X * # of bytes after compression. Returns 0 on write error. Pass file =
X * NULL to just find out length, otherwise will write compressed row to
X * file.
X */
X
XSTATIC unsigned int
Xpack_row(file, source, size)
XFILE *file;
Xchar *source;
Xint size;
X{
X char c,
X lastc = '\0';
X short mode = DUMP;
X short nbuf = 0; /* Number of chars in buffer */
X short rstart = 0; /* Buffer index current run starts */
X unsigned short putsize;
X
X#if OLD
X char buf[MAXDAT * 3 / 2]; /* I think MAXDAT+1 would
X * suffice */
X
X#else
X /*
X * And I think that buf can be changed into a pointer to the source
X * line, to the beginning of a dump. Saves stack space and copying.
X */
X char *buf;
X
X#endif
X
X putsize = 0;
X#if OLD
X buf[0] = lastc = *source++; /* So have valid lastc */
X#else
X buf = source;
X lastc = *source++; /* So have valid lastc */
X#endif
X nbuf = 1;
X size--; /* Since one byte eaten */
X
X
X for (; size; --size) {
X#if OLD
X buf[nbuf++] = c = *source++;
X#else
X nbuf++;
X c = *source++;
X#endif
X switch (mode) {
X case DUMP:
X /*
X * If the buffer is full, write the length byte, then the data
X */
X if (nbuf > MAXDAT) {
X if (file != NULL) {
X if (putc(nbuf - 2, file) == EOF)
X return 0;
X if (fwrite(buf, nbuf - 1, 1, file) != 1)
X return 0;
X }
X putsize += nbuf;
X#if OLD
X buf[0] = c;
X#else
X buf = source - 1; /* Undo the previous source++ */
X#endif
X nbuf = 1;
X rstart = 0;
X break;
X }
X if (c == lastc) {
X if (nbuf - rstart >= MINRUN) {
X if (rstart > 0) {
X if (file != NULL) {
X if (putc(rstart - 1, file) == EOF)
X return 0;
X if (fwrite(buf, rstart, 1, file) != 1)
X return 0;
X }
X putsize += rstart + 1;
X }
X mode = RUN;
X } else if (rstart == 0)
X mode = RUN;
X /*
X * No dump in progress, so can't lose by making these 2 a
X * run.
X */
X } else
X rstart = nbuf - 1; /* First of run */
X break;
X
X case RUN:
X if ((c != lastc) || (nbuf - rstart > MAXRUN)) {
X /*
X * Output run
X */
X if (file != NULL) {
X if (putc(-(nbuf - rstart - 2), file) == EOF)
X return 0;
X if (putc(lastc, file) == EOF)
X return 0;
X }
X putsize += 2;
X#if OLD
X buf[0] = c;
X#else
X buf = source - 1; /* Undo the previous source++ */
X#endif
X nbuf = 1;
X rstart = 0;
X mode = DUMP;
X }
X break;
X }
X
X lastc = c;
X }
X
X switch (mode) {
X case DUMP:
X if (file != NULL) {
X if (putc(nbuf - 1, file) == EOF)
X return 0;
X if (fwrite(buf, nbuf, 1, file) != 1)
X return 0;
X }
X putsize += nbuf + 1;
X break;
X case RUN:
X if (file != NULL) {
X if (putc(-(nbuf - rstart - 1), file) == EOF)
X return 0;
X if (putc(lastc, file) == EOF)
X return 0;
X }
X putsize += 2;
X break;
X }
X return putsize;
X}
X
X/*
X * write_row - pass source line pointer, length of line, and file. Returns
X * # of bytes after not compressing. Returns 0 on write error. Pass file
X * = NULL to just find out length, otherwise will write non-compressed row
X * to file.
X */
X
XSTATIC unsigned int
Xwrite_row(file, source, size)
XFILE *file;
Xchar *source;
Xint size;
X{
X if (file) {
X if (fwrite(source, size, 1, file) != 1)
X return 0;
X }
X return size;
X}
X
X
XSTATIC unsigned long
Xpack_window(file, window, writer)
XFILE *file;
Xregister struct Window *window;
Xregister unsigned int (*writer) ();
X
X{
X unsigned short i,
X j;
X unsigned row_length;
X unsigned long compressed_length;
X unsigned plane_offset;
X int BytesPerRow;
X int YSize;
X ULONG SrcX,
X SrcY;
X struct RastPort Rp;
X struct BitMap Bitmap;
X
X#ifdef DEBUG
X printf("pack_window( %lx %lx)\n", file, window);
X#endif DEBUG
X
X compressed_length = 0;
X plane_offset = 0;
X
X BytesPerRow = line_bytes(window->GZZWidth);
X Bitmap.Depth = window->WScreen->BitMap.Depth;
X if (window->Flags & GIMMEZEROZERO) {
X SrcX = 0;
X SrcY = 0;
X } else {
X SrcX = window->BorderLeft;
X SrcY = window->BorderTop;
X }
X YSize = MAXPLANESIZE / BytesPerRow;
X InitBitMap(&Bitmap, (ULONG) Bitmap.Depth,
X (ULONG) (8 * BytesPerRow), (ULONG) YSize);
X
X /*
X * Make sure the Planes are all NULL so can free up memory easily on
X * error abort
X */
X for (i = 0; i < 8; i++)
X Bitmap.Planes[i] = NULL;
X
X for (i = 0; i < Bitmap.Depth; i++) {
X if ((Bitmap.Planes[i] = ralloc(MAXPLANESIZE)) == NULL) {
X#ifdef DEBUG
X printf("couldn't alloc plane %d in pack_window\n", i);
X printf("pack_window: aborting; free_planes\n");
X#endif
X free_planes(&Bitmap);
X return 0;
X }
X }
X InitRastPort(&Rp);
X Rp.BitMap = &Bitmap;
X#ifdef DEBUG
X printf("pack_window BytesPerRow=%ld Depth=%ld\n", (long) BytesPerRow,
X (long) Bitmap.Depth);
X#endif
X
X for (i = 0; i < window->GZZHeight; i++) {
X if (plane_offset == 0) {
X#ifdef DEBUG
X printf("pack_window ClipBlit SrcX=%ld SrcY=%ld YSize=%ld\n",
X SrcX, SrcY, (ULONG) YSize);
X#endif
X#define DestX 0L
X#define DestY 0L
X ClipBlit(window->RPort, SrcX, SrcY,
X &Rp, DestX, DestY,
X (ULONG) window->GZZWidth, (ULONG) YSize,
X COPY_MINTERM);
X#undef DestX
X#undef DestY
X SrcY += YSize;
X }
X for (j = 0; j < Bitmap.Depth; j++) {
X if ((row_length = (*writer) (file, Bitmap.Planes[j] + plane_offset,
X BytesPerRow)) == 0) {
X#ifdef DEBUG
X printf("error packing row %d plane %d\n", i, j);
X printf("pack_window: aborting; free_planes\n");
X#endif
X free_planes(&Bitmap);
X return 0;
X }
X compressed_length += row_length;
X }
X
X plane_offset += BytesPerRow;
X if (plane_offset > MAXPLANESIZE - BytesPerRow)
X plane_offset = 0;
X }
X
X#ifdef DEBUG
X printf("pack_window: free_planes\n");
X#endif
X free_planes(&Bitmap);
X
X if (compressed_length & 1) {/* Check to see odd length */
X if (file != NULL) {
X if (putc(0, file) == EOF) {
X return 0;
X }
X }
X /*
X * compressed_length++; Deleted!!! Padding should NOT be included
X * in the chunk size !!!
X */
X }
X return compressed_length;
X}
X
Xint
Xwrite_iff(name, colors, window, xoff, yoff, compressed, MandSize, MandPointer)
Xchar *name;
Xunsigned char *colors;
Xregister struct Window *window;
Xshort xoff,
X yoff;
Xshort compressed;
Xint MandSize;
XAPTR MandPointer;
X{
X FILE *file;
X struct form_chunk chunk;
X struct iff_chunk ichunk;
X struct BitMapHeader header;
X long bits_size;
X short i;
X int width = 0;
X int Depth;
X int BytesPerRow;
X
X#ifdef DEBUG
X printf("write_iff\n");
X#endif
X
X if ((file = fopen(name, "w")) == 0) {
X#ifdef PARANOID
X printf("couldn't fopen %s to write\n", name);
X#endif PARANOID
X goto abort;
X }
X /*
X * Say its a FORM ILBM
X */
X chunk.fc_type.b4_type = FORM;
X chunk.fc_subtype.b4_type = ILBM;
X#ifdef MANDEL
X chunk.fc_length = 4 + 3 * sizeof (struct iff_chunk) + MAXCOL * 3 +
X sizeof (struct BitMapHeader) + sizeof (struct CommodoreAmiga) + MandSize;
X#else
X chunk.fc_length = 4 + 3 * sizeof (struct iff_chunk) + MAXCOL * 3 +
X sizeof (struct BitMapHeader) + sizeof (struct CommodoreAmiga);
X#endif MANDEL
X if (window) {
X width = window->GZZWidth;
X BytesPerRow = line_bytes(width);
X Depth = window->WScreen->BitMap.Depth;
X if (compressed) {
X#ifdef DEBUG
X printf("write_iff: call pack_window for sizing\n");
X#endif
X if ((bits_size = pack_window(NULL, window, pack_row)) == 0)
X goto abort;
X } else {
X bits_size = BytesPerRow * window->GZZHeight * Depth;
X }
X chunk.fc_length += bits_size;
X if (bits_size & 1)
X chunk.fc_length++;
X }
X if (fwrite(&chunk, sizeof (chunk), 1, file) != 1)
X goto abort;
X
X /*
X * Here comes a BitMapHeader
X */
X {
X struct iff_chunk ichunk;
X
X ichunk.iff_type.b4_type = BMHD;
X ichunk.iff_length = sizeof (header);
X if (fwrite(&ichunk, sizeof (ichunk), 1, file) != 1)
X goto abort;
X }
X
X /*
X * Initialize the BitMapHeader to normal values
X */
X header.masking = 0;
X header.pad1 = 0;
X header.transparentColor = 0;
X if (compressed)
X header.compression = 1;
X else
X header.compression = 0;
X header.pageWidth = width;
X header.pageHeight = window ? window->GZZHeight : YMAX;
X header.xAspect = width > LOXMAX ? XASPECT : XASPECT * 2;
X header.yAspect = YASPECT;
X /*
X * If it's not just a color map give the dimensions of rasters
X */
X if (window) {
X header.w = width;
X header.h = window->GZZHeight;
X header.nPlanes = Depth;
X header.x = xoff;
X header.y = yoff;
X }
X if (fwrite(&header, sizeof (header), 1, file) != 1)
X goto abort;
X
X /*
X * Squirt out the color map
X */
X {
X struct iff_chunk ichunk;
X
X ichunk.iff_type.b4_type = CMAP;
X ichunk.iff_length = MAXCOL * 3;
X if (fwrite(&ichunk, sizeof (ichunk), 1, file) != 1)
X goto abort;
X if (fwrite(colors, (int) 3 * MAXCOL, 1, file) != 1)
X goto abort;
X }
X
X /*
X * Write a CAMG chunk with ViewPort modes
X */
X {
X struct CommodoreAmiga camg;
X
X camg.camg_iffc.iff_type.b4_type = CAMG;
X camg.camg_iffc.iff_length = sizeof (camg) - sizeof (camg.camg_iffc);
X camg.camg_data = window->WScreen->ViewPort.Modes;
X if (fwrite(&camg, sizeof (camg), 1, file) != 1)
X goto abort;
X }
X
X#ifdef MANDEL
X /*
X * We want to write our own private MAND chunk
X */
X if (MandSize) {
X if (fwrite(MandPointer, MandSize, 1, file) != 1)
X goto abort;
X }
X#endif MANDEL
X
X /*
X * If they be bits then squirt out the bits
X */
X if (window) {
X struct iff_chunk ichunk;
X
X ichunk.iff_type.b4_type = BODY;
X ichunk.iff_length = bits_size;
X if (fwrite(&ichunk, sizeof (ichunk), 1, file) != 1)
X goto abort;
X#ifdef DEBUG
X printf("write_iff: call pack_window for real\n");
X#endif
X if (compressed) {
X if (pack_window(file, window, pack_row) == 0)
X goto abort;
X } else {
X if (pack_window(file, window, write_row) == 0)
X goto abort;
X }
X }
X fclose(file);
X
X return 1;
Xabort:
X#ifdef DEBUG
X printf("write_iff: aborting !!!\n");
X#endif
X fclose(file);
X return 0;
X}
X
X
X/*
X * put_ea_cmap given an ea-type color map:
X *
X * an array of unsigned chars of form ea_cmap[] = {r, g, b, r, g, b...}
X *
X * turn it into an amiga-type color map:
X *
X * an array of unsigned short of form amiga_cmap = {0xrgb, 0xrgb, ...}
X *
X * and then tell Dale this is the colors we want for our viewport
X */
X
Xvoid
Xput_ea_cmap(ea_cmap, colors, Screen)
Xunsigned char *ea_cmap;
Xint colors;
Xstruct Screen *Screen;
X{
X unsigned short amy_cmap[MAXCOL];
X register int i;
X register short color;
X
X if (colors > MAXCOL) /* Color clipping */
X colors = MAXCOL;
X for (i = 0; i < colors; i++) {
X color = (*ea_cmap++ & 0xF0) << 4;
X color |= *ea_cmap++ & 0xF0;
X color |= (*ea_cmap++ & 0xF0) >> 4;
X amy_cmap[i] = color;
X }
X LoadRGB4(&Screen->ViewPort, amy_cmap, (long) colors);
X}
X
Xvoid
Xget_ea_cmap(ea_cmap, colors, Screen)
Xunsigned char *ea_cmap;
Xint colors;
Xstruct Screen *Screen;
X{
X register long i;
X register unsigned short rgb;
X
X if (colors > MAXCOL) /* Color clipping */
X colors = MAXCOL;
X for (i = 0; i < colors; i++) {
X rgb = GetRGB4(Screen->ViewPort.ColorMap, i);
X *ea_cmap++ = (rgb & 0xF00) >> 4;
X *ea_cmap++ = (rgb & 0x0F0);
X *ea_cmap++ = (rgb & 0x00F) << 4;
X }
X}
SHAR_EOF
echo "End of archive 2 (of 4)"
# if you want to concatenate archives, remove anything after this line
exit